/**
 * OWASP GoatDroid Project
 * 
 * This file is part of the Open Web Application Security Project (OWASP)
 * GoatDroid project. For details, please see
 * https://www.owasp.org/index.php/Projects/OWASP_GoatDroid_Project
 *
 * Copyright (c) 2011 - The OWASP Foundation
 * 
 * GoatDroid is published by OWASP under the GPLv3 license. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 * 
 * @author Jack Mannino, nVisium Security (https://www.nvisiumsecurity.com)
 * @created 2011
 */
package org.owasp.goatdroid.fourgoats.webservice.friends;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import org.owasp.goatdroid.fourgoats.webservice.Constants;
import org.owasp.goatdroid.fourgoats.webservice.friends.beans.FriendListBean;
import org.owasp.goatdroid.fourgoats.webservice.friends.beans.FriendProfileBean;
import org.owasp.goatdroid.fourgoats.webservice.friends.beans.FriendsBean;
import org.owasp.goatdroid.fourgoats.webservice.friends.beans.PendingFriendRequestsBean;
import org.owasp.goatdroid.fourgoats.webservice.friends.beans.PublicUsersBean;
import org.owasp.goatdroid.fourgoats.webservice.login.LoginImpl;
import org.owasp.goatdroid.fourgoats.webservice.validators.Validators;

public class FriendsImpl {

	static public FriendListBean getFriends(String sessionToken) {

		FriendListBean bean = new FriendListBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			try {
				FriendsDAO dao = new FriendsDAO();
				String userID = dao.getUserID(sessionToken);
				String userName = dao.getUserName(userID);
				HashMap<String, String> friends = dao.getFriends(userID,
						userName);
				bean.setFriends(friends);
				dao.closeConnection();
				bean.setSuccess(true);
				return bean;
			} catch (InstantiationException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (IllegalAccessException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (ClassNotFoundException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (SQLException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			}
		} else
			errors.add(Constants.INVALID_SESSION);

		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;
	}

	static public FriendsBean requestFriend(String sessionToken,
			String friendUserName) {

		FriendsBean bean = new FriendsBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			if (Validators.validateUserNameFormat(friendUserName)) {
				try {
					FriendsDAO dao = new FriendsDAO();
					String userID = dao.getUserID(sessionToken);
					String friendUserID = dao.getUserIDByName(friendUserName);
					if (!dao.isFriend(userID, friendUserID)) {
						if (!dao.wasFriendRequestSent(friendUserID, userID)) {
							if (!userID.equals(friendUserID)) {
								dao.requestFriend(userID, friendUserID);
								dao.closeConnection();
								bean.setSuccess(true);
								return bean;
							} else {
								errors.add(Constants.CANNOT_DO_TO_YOURSELF);
								dao.closeConnection();
							}
						} else {
							errors.add(Constants.FRIEND_ALREADY_REQUESTED);
							dao.closeConnection();
						}
					} else {
						errors.add(Constants.ALREADY_FRIENDS);
						dao.closeConnection();
					}
				} catch (InstantiationException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (IllegalAccessException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (ClassNotFoundException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (SQLException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				}
			} else
				errors.add(Constants.UNEXPECTED_ERROR);
		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;
	}

	static public FriendsBean acceptOrDenyFriendRequest(String action,
			String sessionToken, String userName) {

		FriendsBean bean = new FriendsBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			if (Validators.validateUserNameFormat(userName)) {
				try {
					FriendsDAO dao = new FriendsDAO();
					String userID = dao.getUserID(sessionToken);
					String friendRequestID = dao.getFriendRequestID(userName,
							userID);
					if (dao.isUserFriendRequested(userID, friendRequestID)) {
						String fromUserID = dao
								.getFromFriendID(friendRequestID);
						if (action.equals("accept")) {
							dao.addFriend(userID, fromUserID);
							dao.removePendingFriendRequest(friendRequestID);
						} else {
							dao.removePendingFriendRequest(friendRequestID);
						}
						dao.closeConnection();
						bean.setSuccess(true);
						return bean;
					} else {
						dao.closeConnection();
						errors.add(Constants.NOT_AUTHORIZED);
					}
				} catch (InstantiationException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (IllegalAccessException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (ClassNotFoundException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (SQLException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				}
				bean.setErrors(errors);
				bean.setSuccess(false);
				return bean;
			} else
				errors.add(Constants.UNEXPECTED_ERROR);
		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setErrors(errors);
		bean.setSuccess(false);
		return bean;
	}

	static public FriendsBean removeFriend(String sessionToken,
			String friendUserName) {

		FriendsBean bean = new FriendsBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			if (Validators.validateUserNameFormat(friendUserName)) {
				try {
					FriendsDAO dao = new FriendsDAO();
					String userID = dao.getUserID(sessionToken);
					String friendUserID = dao.getUserIDByName(friendUserName);
					if (!userID.equals(friendUserID)) {
						if (dao.isFriend(userID, friendUserID)) {
							dao.removeFriend(userID, friendUserID);
							bean.setSuccess(true);
							return bean;
						} else {
							errors.add(Constants.NOT_AUTHORIZED);
							dao.closeConnection();
						}

					} else {
						dao.closeConnection();
						errors.add(Constants.CANNOT_DO_TO_YOURSELF);
					}
				} catch (InstantiationException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (IllegalAccessException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (ClassNotFoundException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (SQLException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				}
			} else
				errors.add(Constants.UNEXPECTED_ERROR);
		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setErrors(errors);
		bean.setSuccess(false);
		return bean;
	}

	static public FriendProfileBean getProfile(String sessionToken,
			String friendUserName) {
		FriendProfileBean bean = new FriendProfileBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			if (Validators.validateUserNameFormat(friendUserName)) {
				try {
					FriendsDAO dao = new FriendsDAO();
					String userID = dao.getUserID(sessionToken);
					String friendUserID = dao.getUserIDByName(friendUserName);
					if (dao.isFriend(userID, friendUserID)
							|| dao.isProfilePublic(friendUserID)
							|| userID.equals(friendUserID)) {
						bean.setProfile(dao.getProfile(friendUserID));
						bean.setSuccess(true);
						return bean;
					} else {
						dao.closeConnection();
						errors.add(Constants.NOT_AUTHORIZED);
					}
				} catch (InstantiationException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (IllegalAccessException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (ClassNotFoundException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				} catch (SQLException e) {
					errors.add(Constants.UNEXPECTED_ERROR);
				}
			} else
				errors.add(Constants.UNEXPECTED_ERROR);
		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;
	}

	static public PendingFriendRequestsBean getPendingFriendRequests(
			String sessionToken) {

		PendingFriendRequestsBean bean = new PendingFriendRequestsBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {

			try {
				FriendsDAO dao = new FriendsDAO();
				String userID = dao.getUserID(sessionToken);
				HashMap<String, String> requests = dao
						.getPendingFriendRequests(userID);
				dao.closeConnection();
				bean.setPendingFriendRequests(requests);
				bean.setSuccess(true);
				return bean;
			} catch (InstantiationException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (IllegalAccessException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (ClassNotFoundException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (SQLException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			}
		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setSuccess(false);
		bean.setErrors(errors);
		return bean;
	}

	static public PublicUsersBean getPublicUsers(String sessionToken) {
		PublicUsersBean bean = new PublicUsersBean();
		ArrayList<String> errors = new ArrayList<String>();
		if (LoginImpl.isSessionValid(sessionToken)
				&& Validators.validateSessionTokenFormat(sessionToken)) {
			try {
				FriendsDAO dao = new FriendsDAO();
				String userName = dao.getUserNameBySessionToken(sessionToken);
				HashMap<String, String> users = dao.getPublicUsers(userName);
				dao.closeConnection();
				bean.setUsers(users);
				bean.setSuccess(true);
				return bean;
			} catch (InstantiationException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (IllegalAccessException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (ClassNotFoundException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			} catch (SQLException e) {
				errors.add(Constants.UNEXPECTED_ERROR);
			}

		} else
			errors.add(Constants.INVALID_SESSION);
		bean.setErrors(errors);
		bean.setSuccess(false);
		return bean;
	}
}
